<template>
    <div :class="'Image type-'+type" v-bind="$attrs">
        <span class="loading" v-if="loading">
            <van-loading color="black"/>
        </span>
        <img :src="src" alt="" v-else>
    </div>
</template>
<script>
    import {Loading} from 'vant';
    // 缓存图片
    window.ImgsCache = {};
    export default {
        components: {
            [Loading.name]: Loading
        },
        props: {
            src: {
                default: ''
            }
        },
        data() {
            return {
                type: 'w-full',
                loading: true
            }
        },
        watch: {
            src(n, o) {
                if (n !== o) {
                    this.load(n);
                }
            }
        },
        created() {
            this.$nextTick(() => {
                this.load(this.src)
            })
        },
        methods: {
            singleTon() {
                let imgObj = window.ImgsCache[this.src];
                if (imgObj) {
                    this.loading = false;
                    this.type = imgObj.type;
                    return imgObj.image
                }
                return false
            },
            load(src) {
                this.loading = true;
                let cacheSingle = this.singleTon();
                if (cacheSingle) {
                    return;
                }
                let image = new Image();
                this.loading = false;
                let {
                    $el: {
                        parentNode: {
                            offsetWidth: width = 0,
                            offsetHeight: height = 0,
                        } = {}
                    } = {}
                } = this;
                const x_y_box = width / height;
                image.onload = () => {
                    const x_y = image.width / image.height;
                    // 正方形外框
                    if (x_y_box === 1 || !width || !height) {
                        this.type = image.width > image.height ? 'h-full' : 'w-full';
                    }
                    // 图片比外框更扁
                    else if (x_y > x_y_box) {
                        this.type = 'h-full';
                    }
                    // 高正方形
                    else {
                        this.type = 'w-full';
                    }
                    window.ImgsCache[src] = {
                        type: this.type,
                        image
                    }
                };
                image.onerror = () => {
                    this.loading = false;
                };
                image.src = src;
            }
        }
    }
</script>
<style lang="scss" scoped>
    .Image {
        width: 100%;
        height: 100%;
        position: relative;
        overflow: hidden;
        z-index: 1;
        img,
        .loading {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }
        // 宽高图片决定
        // 最小宽高由外框决定
        &.type-min-full {
            img {
                min-height: 100%;
                min-width: 100%;
            }
        }
        // 宽高最大由外框决定
        &.type-max-full {
            img {
                max-height: 100%;
                max-width: 100%;
            }
        }
        // 宽高完全填满
        &.type-full {
            img {
                height: 100%;
                width: 100%;
            }
        }
        // 宽最大由外框决定
        &.type-w-full {
            img {
                max-width: 100%;
                min-width: 100%;
            }
        }
        // 高最大由外框决定
        &.type-h-full {
            img {
                max-height: 100%;
                min-height: 100%;
            }
        }
    }
</style>
